package com.mldong.modules.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.*;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mldong.base.CommonPage;
import com.mldong.base.LabelValueVO;
import com.mldong.base.PageParam;
import com.mldong.holder.LoginUserHolder;
import com.mldong.modules.sys.dto.RolePageParam;
import com.mldong.modules.sys.dto.RoleParam;
import com.mldong.modules.sys.entity.Role;
import com.mldong.modules.sys.mapper.RoleMapper;
import com.mldong.modules.sys.service.RoleService;
import com.mldong.modules.sys.vo.RoleVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 角色 服务实现类
 * </p>
 *
 * @author mldong
 * @since 2022-10-22
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(RoleParam param) {
        param.setId(null);
        Role Role = new Role();
        BeanUtil.copyProperties(param, Role);
        return super.save(Role);
    }

    @Override
    public boolean update(RoleParam param) {
        Role Role = new Role();
        BeanUtil.copyProperties(param, Role);
        return super.updateById(Role);
    }

    @Override
    public CommonPage<RoleVO> page(RolePageParam param) {
        IPage<RoleVO> page = param.buildMpPage();
        QueryWrapper queryWrapper = param.buildQueryWrapper();
        queryWrapper.eq("t.is_deleted",0);
        List<RoleVO> list = baseMapper.selectCustom(page, queryWrapper);
        page.setRecords(list);
        return CommonPage.toPage(page);
    }
    @Override
    public RoleVO findById(Long id) {
        return baseMapper.findById(id);
    }

    @Override
    public List<LabelValueVO> select(String module,String tableName, PageParam param) {
        String className = StrUtil.format("com.mldong.modules.{}.mapper.{}Mapper",
                module,StrUtil.upperFirst(tableName));
        // 获取mapper类
        Class<?> clazz = ClassUtil.loadClass(className);
        // 获取mapper-bean
        BaseMapper baseMapper = (BaseMapper) SpringUtil.getBean(clazz);
        // 构造查询
        QueryWrapper queryWrapper = param.buildQueryWrapper();
        List<Object> includeIds = param.getIncludeIds();
        // 获取label-key,默认为name
        String labelKey = StrUtil.isEmpty(param.getLabelKey()) ? "name":param.getLabelKey();
        // 获取值key,默认为id
        String valueKey = StrUtil.isEmpty(param.getValueKey()) ? "id":param.getValueKey();
        Integer includeType = param.getIncludeType();
        if(ObjectUtil.isNotEmpty(includeIds) && ObjectUtil.equals(includeType,2)){
            queryWrapper.in(valueKey,includeIds);
        }
        // 查询
        List<Object> list = baseMapper.selectList(queryWrapper);
        List<Object> valueList = list.stream().map(item->ReflectUtil.getFieldValue(item,valueKey)).collect(Collectors.toList());
        if(ObjectUtil.isNotEmpty(includeIds) && ObjectUtil.equals(includeType,1)){
            // 增量，一定包含includeIds的数据
            QueryWrapper<Object> newQueryWrapper = Wrappers.query();
            newQueryWrapper.in(valueKey, includeIds);
            if(ObjectUtil.isNotEmpty(valueList)){
                newQueryWrapper.notIn(valueKey, valueList);
            }
            List<Object> addList = baseMapper.selectList(newQueryWrapper);
            list.addAll(addList);
        }
        String extFieldNames = param.getExtFieldNames();
        boolean hasExt = ObjectUtil.isNotEmpty(extFieldNames);
        List<LabelValueVO> res = list.stream().map(item->{
            // 通过labelKey去获取label
            String label = StrUtil.toString(ReflectUtil.getFieldValue(item,labelKey));
            // 通过valueKey获取值
            Object value = ReflectUtil.getFieldValue(item,valueKey);
            if(!LoginUserHolder.get().isSuperAdmin()){
                if("mobilePhone".equalsIgnoreCase(labelKey)){
                    label = PhoneUtil.hideBetween(StrUtil.toString(label)).toString();
                }
                if("mobilePhone".equalsIgnoreCase(valueKey)){
                    value = PhoneUtil.hideBetween(StrUtil.toString(value));
                }
            }
            Dict ext = Dict.create();
            if(hasExt){
                String fieldNames [] = extFieldNames.split(",");
                for (String s : fieldNames) {
                    if(ReflectUtil.hasField(item.getClass(),s)){
                        ext.set(s,ReflectUtil.getFieldValue(item,s));
                        // 如果key为手机号，则隐藏中心
                        if(!LoginUserHolder.get().isSuperAdmin()){
                            if("mobilePhone".equalsIgnoreCase(s)){
                                ext.set(s, PhoneUtil.hideBetween(StrUtil.toString(ReflectUtil.getFieldValue(item,s))));
                            }
                        }
                    }
                }
            }
            return LabelValueVO.builder().label(label).value(value).ext(ext).build();
        }).collect(Collectors.toList());
        return res;

    }
}
